﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using Microsoft.Practices.Prism.Interactivity;
using Microsoft.Practices.Prism.UnityExtensions;
using System.Collections.ObjectModel;
using Module.Model;
using Microsoft.Practices.Prism.Commands;
using System.Windows;
using Module.Service;
using System.IO;

namespace Module.ViewModel
{
    public class PersonViewModel: INotifyPropertyChanged, IDataErrorInfo
    {
        #region Data

        private Person _person { get; set; }
        private ObservableCollection<PersonViewModel> _children { get; set; }
        private ObservableCollection<StepViewModel> _steps { get; set; }
        
        private Visibility _visibilityTextBlock { get; set; }
        private Visibility _visibilityTextBox { get; set; }
        private Visibility _visibilitySearch { get; set; }
        private string _firstChild { get; set; }

        private bool _isFocus { get; set; }

        public DelegateCommand<object> NewPersonCommand { get; set; }
        public DelegateCommand<object> RenamePersonCommand { get; set; }
        public DelegateCommand<object> LostFocusTextBoxCommand { get; set; }
        public DelegateCommand<object> RemovePersonCommand { get; set; }
        public DelegateCommand<object> TextChangeCommand { get; set; }
        public DelegateCommand<object> RichTextBoxCommand { get; set; }

        

        private string name { get; set; }

        #endregion Data

        #region Constructor

        public PersonViewModel(Person person)
        {
            this._person = person;

            this.name = _person.Name;

            this._children = new ObservableCollection<PersonViewModel>();
            this._steps = new ObservableCollection<StepViewModel>();

            this._visibilityTextBlock = Visibility.Visible;
            this._visibilityTextBox = Visibility.Collapsed;
            this._visibilitySearch = Visibility.Collapsed;

            this._isFocus = false;
            this._firstChild = string.Empty;
            
            foreach(Person childPerson in person.Children)
            {
                this._children.Add(new PersonViewModel(childPerson));                
            }

            foreach (Step step in person.Steps)
            {
                this._steps.Add(new StepViewModel(step));
            }

            Steps.CollectionChanged += OnGroceryListChanged;

            this.NewPersonCommand = new DelegateCommand<object>(CallNewPersonCommand, CanExecute);
            this.RenamePersonCommand = new DelegateCommand<object>(CallRenamePersonCommand, CanExecute);
            this.LostFocusTextBoxCommand = new DelegateCommand<object>(CallLostFocusTextBoxCommand, CanExecute);
            this.RemovePersonCommand = new DelegateCommand<object>(CallRemovePersonCommand, CanExecute);
            this.TextChangeCommand = new DelegateCommand<object>(CallTextChangeCommand, CanExecute);
            this.RichTextBoxCommand = new DelegateCommand<object>(CallRichTextBoxCommand, CanExecute);          
        }

        public Person Person
        {
            get
            {
                return _person;
            }
            set
            {
                if (this._person != value)
                {
                    _person = value;
                    NotifyPropertyChanged("Person");
                }
            }
        }

        public ObservableCollection<PersonViewModel> Children
        {
            get
            {
                return _children;
            }
            set
            {
                if (this._children != value)
                {
                    _children = value;
                    NotifyPropertyChanged("Children");
                }
            }
        }

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                if (this.name != value)
                {
                    name = value;
                    NotifyPropertyChanged("Name");
                }
            }
        }

        public Visibility VisibilityTextBlock
        {
            get
            {
                return _visibilityTextBlock;
            }
            set
            {
                if (this._visibilityTextBlock != value)
                {
                    _visibilityTextBlock = value;
                    NotifyPropertyChanged("VisibilityTextBlock");
                }
            }
        }

        public Visibility VisibilityTextBox
        {
            get
            {
                return _visibilityTextBox;
            }
            set
            {
                if (this._visibilityTextBox != value)
                {
                    _visibilityTextBox = value;
                    NotifyPropertyChanged("VisibilityTextBox");
                }
            }
        }

        public Visibility VisibilityTextSearch
        {
            get
            {
                return _visibilitySearch;
            }
            set
            {
                if (this._visibilitySearch != value)
                {
                    this._visibilitySearch = value;
                    NotifyPropertyChanged("VisibilityTextSearch");
                }
            }
        }

        public bool IsFocused
        {
            get
            {
                return _isFocus;
            }
            set
            {
                if (this._isFocus != value)
                {
                    this._isFocus = value;
                    NotifyPropertyChanged("IsFocused");
                }
            }
        }

        public string FirstChild
        {
            get
            {
                return _firstChild;
            }
            set
            {
                if (this._firstChild != value)
                {
                    this._firstChild = value;
                    NotifyPropertyChanged("FirstChild");
                }
            }
        }

        public ObservableCollection<StepViewModel> Steps
        {
            get
            {
                return _steps;
            }
            set
            {
                _steps = value;
                NotifyPropertyChanged("Steps");
            }
        }

        public StepViewModel SelectedStep { get; set; }

        public string this[string propertyname]
        {
            get
            {
                if (propertyname == "Name")
                {
                    if (string.IsNullOrEmpty(Name))
                        return "Please enter a name";
                    try
                    {
                        int a = int.Parse(Name);
                        if (a < 0)
                            return "The number cann't less than 0";
                    }
                    catch (FormatException)
                    {
                        return "Please enter corrent number";
                    }
                    catch (OverflowException)
                    {
                        return "The number too long";
                    }                   
                  
                }
                return null;
            }
        }

        public string Error
        {
            get
            {
                throw new NotImplementedException();
            }            
        }
       
        #endregion Constructor
       
        #region Event
        public bool CanExecute(object arg)
        {
            return true;
        }

        public void CallNewPersonCommand(object obj)
        {
            Person newPerson = new Person("New Person");
            this.Children.Add(new PersonViewModel(newPerson));
        }
       
        public void CallRenamePersonCommand(object obj)
        {
            VisibilityTextBlock = Visibility.Collapsed;
          
            VisibilityTextBox = Visibility.Visible;
            IsFocused = true;
        }

        public void CallLostFocusTextBoxCommand(object obj)
        {
            VisibilityTextBlock = Visibility.Visible;

            VisibilityTextBox = Visibility.Collapsed;
            IsFocused = false;

           // Global.ModuleAViewModel.CanEnable = Visibility.Visible;
        }

        public void CallRemovePersonCommand(object obj)
        {
            
        }

        public void CallTextChangeCommand(object obj)
        {

        }

        public void CallRichTextBoxCommand(object obj)
        {
        }


        void OnGroceryListChanged(object sender,
        System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {

            // Resequence list
            SequencingService.SetCollectionSequence(this.Steps);
        }


        #endregion Event

        #region NotifyPropertyChanged Member
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion NotifyPropertyChanged Member

    }
}
